/*
--------------------------------------------------------------------------------
				Ak-Lib. 
			 Project       	: Ak-Lib
			 Group         	: Ak-Lib R&D Team
			 Author        	: Ocean.Wang
			 Create Date 	: 05-01-2010
--------------------------------------------------------------------------------
Code Name 	:  A.K 	~v~
Description	:  Yet Another Cross-Platform Lib.
Cautions    	:
--------------------------------------------------------------------------------
Change History:
Version		: 0.1
Building 		: 05/01/10
10-05.01 first draft, build, debug and test.
--------------------------------------------------------------------------------
*/

#ifndef _INC_AK_LINK_
#define	_INC_AK_LINK_

#include "ak_types.h"
#include "ak_queue.h"
#include "ak_jobq.h"
#include "ak_socket.h"
#include "ak_mem.h"

#ifdef __cplusplus
extern "C" {
#endif

/* ------------------------------------------------------------------
** Transport Layer 
*/
typedef int 	(* 	IOFunc_DataInd)(	void 		  *	pLink, 		void 		* 	pCookie,  
										unsigned char * pBuf, 		int 			lBuf, 
										unsigned int 	ipAddr, 	unsigned short 	port, 
										unsigned int 	ppId);

typedef int 	(* 	IOFunc_StateInd)(void * pLink, void * pCookie, int type);

typedef struct{
	IOFunc_DataInd 		dataInd;
	IOFunc_StateInd		stateInd;
}_t_ioFunc;


/* =====================================================================
** 	Net I/O Link.
*/
/*  Error Type */
typedef enum _e_ioLinkErr{
	ERR_LINK_UNKNOWN,
	ERR_LINK_OP,
	ERR_LINK_FD,
	ERR_LINK_NETWORK,
	ERR_LINK_MAX
}_e_ioLinkErr;

/* Link OP */
#define _LINKOP_ADD			0X1000
#define _LINKOP_DEL			0X2000

#define _LINKOP_MSG			0X8000
#define _LINKOP_FUNC		0X8001
#define _LINKOP_ASYNC		0X8002


/* I/O Callback */
typedef struct{
	/* User's Callback Interface */
	/* Link Ctrl :  */
	int 			(*	cbConn)();	/* Cli:Connect */
	int 			(*	cbAcpt)(); 	/* Svr:Accept */
	int 			(*	cbErr )();	/* Error 		*/

	/* Link Data : Tx & Rx */
	int 			(* 	cbTxSche)();	/* TxSche 	*/
	int 			(* 	cbRxSche)();	/* RxSche 	*/

	/* User Msg & Notify */
	int 			(* 	cbMisc)();
}_t_ioCbUser;


/* I/O Link Job */
typedef struct _t_ioLinkJob{
	int 			index;
	/* Job Que */
	_t_sysJobQ 		jobHi;
	_t_sysJobQ 		jobLo;

	/* Handle of Event Sel */
	_t_sysEvSel * 	pEvSel;

	/* Hashing Tree, RSI Queues */
	_t_sysCS 		lock;
	_t_rbroot 		linkTree;
	
	_t_rsiQue 		txQ;
	_t_rsiQue 		rxQ;
	unsigned long 	linkStat;
}_t_ioLinkJob;


/* I/O Link Node */
typedef struct 	_t_ioLinkCi{
	/* Rb Tree Support */
	_t_sysMi 		mi;

	/* Tx & Rx Ready-Stdby-Idle Event Trigger Node */
	_t_rsiNode 		txNode;
	_t_rsiNode 		rxNode;

	/* Schedule */
	int 			bSche;						

	/* Job & Port */
	_t_ioLinkJob   * pJob;

	/* User Hint */
	void 		* 	hUser;
	long 			lUser;
	_t_ioCbUser *	cbUser;

	/* Cas */
	unsigned long 	casId;
	_t_sysMPool   * pPool;

	/* I/O & Event. */
	#if 0
	_u_ipport		local;
	_u_ipport		remote;
	#endif
	_t_ioFunc 	* 	ioFunc;
	_t_sockEvUser	eUser;
}_t_ioLinkCi;

extern	int 	ioLink_Init(_t_ioLinkCi * pLink, S_SOCKET fd, _e_sockType type, _t_sockFunc * pSFunc, unsigned long eCase);
extern	void 	ioLink_Rm(_t_ioLinkCi * pLink);

/* IO Func, Cookie, CasId */
extern	int 	ioLink_SetIoFunc(_t_ioLinkCi * pLink, _t_ioFunc * ioFunc);
extern	int 	ioLink_SetCookie(_t_ioLinkCi * pLink, void * pCookie);
extern	int 	ioLink_GetCasId(_t_ioLinkCi * pLink, unsigned long * pCasId);
extern	int 	ioLink_CmpCasId(_t_ioLinkCi * pNew, _t_ioLinkCi * pOld, unsigned long lCasId);

/*
--------------------------------------------------------------------------------
** 	Link Job Sche
*/

typedef struct{
	/* Trigger */
	_t_cbentry 			trigger;
	unsigned long 		tick;

	/* Reflect to the User Context */
	void 			* 	pCookie;

	/* Job Pool */
	_t_ioLinkJob 		linkJob;
}_t_ioLinkRt;


extern	int 	ioLink_JobInit(_t_ioLinkJob  	* pLinkJob, 	
								_t_sysSemB  	* pWake, 
								_t_sysEvSel 	* pEvSel,
								unsigned int  	  ringHi,	
								unsigned int  	  ringLo);

extern	int 	ioLink_JobSche(_t_ioLinkJob * pLinkJob, _t_sysJobNode ** ppJobNode);
extern	int 	ioLink_Dump(_t_ioLinkJob * pLinkJob);


/* IOLink Command */
extern	int 	SIOLink_SetTraceLvl(int lvl);
extern	int 	SIOLink_GetTraceLvl(void);

#ifdef __cplusplus
}
#endif

#endif


